import faust
import sys

from application.settings import KAFKA_CONFIG, TOPIC_CONFIG
from application.utils import get_logger
from application.utils.logger import add_faust_handlers

# 创建日志记录器
logger = get_logger(__name__)


class FaustAppManager:
    """
    Faust 应用管理器，用于集中管理 Faust 应用的初始化、主题注册及代理函数绑定。

    Attributes
    ----------
    app : faust.App
        Faust 应用实例。
    """

    def __init__(self):
        """
        初始化 FaustAppManager 并创建 Faust 应用实例。
        
        Parameters
        ----------
        auto_offset_reset : str, optional
            Kafka消费者偏移量重置策略。默认为None，使用Faust默认值。
            可选值: 'earliest', 'latest', 'none'
        """
        self.app = None
        self._init_app()

    def _init_app(self):
        """
        初始化 Faust 应用，设置应用名称和 broker 地址，并为应用添加日志处理器。

        Raises
        ------
        Exception
            初始化失败时抛出异常。
        """
        try:
            self.app = faust.App(id=KAFKA_CONFIG['default']['app_name'],
                                 broker=KAFKA_CONFIG['default']['broker'],
                                 # 设置消费者从头开始读取数据
                                 consumer_auto_offset_reset='earliest')

            # 为 Faust 应用添加日志处理器
            add_faust_handlers()
            logger.info(
                "Faust应用初始化完成，应用名: %s, broker地址: %s",
                KAFKA_CONFIG['default']['app_name'],
                KAFKA_CONFIG['default']['broker']
            )
        except Exception as e:
            logger.error("Faust应用初始化失败: %s", str(e))
            raise

    def register_agent(self, topic_name, process_agent, value_type=None):
        """
        注册主题及对应的处理函数代理。

        Parameters
        ----------
        topic_name : str
            Kafka 主题名称。
        process_agent : callable
            处理函数或 Faust Agent，用于处理该主题消息。
        value_type : Optional[faust.Record]
            消息的数据结构类型，可选，用于序列化/反序列化。

        Notes
        -----
        会自动将处理函数绑定到 Faust 应用的 topic 上，并记录日志。
        """
        topic = self.app.topic(topic_name, value_type=value_type)
        logger.info("成功注册主题: %s", topic_name)

        self.app.agent(topic)(process_agent)
        logger.info("成功注册处理函数到主题: %s", topic.get_topic_name())

    def register_timer(self, interval_seconds, timer_func):
        """
        注册定时任务，相当于 @app.timer(interval=interval_seconds)

        Parameters
        ----------
        interval_seconds : float
            执行间隔，单位秒。
        timer_func : callable
            异步函数，作为定时任务执行。
        """
        self.app.timer(interval=interval_seconds)(timer_func)

    def get_app(self):
        """
        获取 Faust 应用实例。

        Returns
        -------
        faust.App
            当前 Faust 应用实例。
        """
        return self.app
